#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"
#include <math.h>

#define DEBUG 0 
#define NOISY_TEST 1

int test_adventurer(int card, int choice1, int choice2, int choice3, struct gameState *post, int handPos, int bonus) {
   struct gameState pre;
   memcpy (&pre, post, sizeof(struct gameState));
   int currentPlayer = whoseTurn(&pre), cardDrawn, drawntreasure = 0;
   int r, z = 0, temphand[MAX_HAND];
   r = cardEffect(card, choice1, choice2, choice3, post, handPos, &bonus);
   //code that changes the gamestate pre, in the same way as an adventurer card.
   while(drawntreasure < 2){
      if(pre.deckCount[currentPlayer] < 1){
	 //Shuffles the deck if out of cards.
	 shuffle(currentPlayer, &pre);
      }
      drawCard(currentPlayer, &pre);
      cardDrawn = pre.hand[currentPlayer][pre.handCount[currentPlayer] - 1];
      if(cardDrawn == copper || cardDrawn == silver || cardDrawn == gold)
	 drawntreasure++;
      else{
	 temphand[z] = cardDrawn;
	 pre.handCount[currentPlayer]--;
	 z++;
      }
   }
   while (z - 1 >= 0){
      pre.discard[currentPlayer][pre.discardCount[currentPlayer]++] = temphand[z - 1];
   z--;
   }

   assert (r == 0);

   assert(memcmp(&pre, post, sizeof(struct gameState)) == 0);
}

int main () {

  int i, n, r, p, deckCount, discardCount, handCount;
  int bonus, handPos;
  int k[10] = {adventurer, council_room, feast, gardens, mine,
	       remodel, smithy, village, baron, great_hall};
  int card = adventurer, choice1 = -1, choice2 = -1, choice3 = -1;

  struct gameState G;

  printf ("Testing adventurer card.\n");

  printf ("RANDOM TESTS.\n");

  SelectStream(2);
  PutSeed(3);
  for (n = 0; n < 2000; n++) {
    initializeGame(2, k, 2, &G);
    p = floor(Random() * 2);
    G.numPlayers = 2;
    G.whoseTurn =  floor(Random() * G.numPlayers);
    G.deckCount[p] = floor(Random() * MAX_DECK);
    G.discardCount[p] = floor(Random() * MAX_DECK);
    G.handCount[p] = floor(Random() * MAX_HAND);
    test_adventurer(card, choice1, choice2, choice3, &G, handPos, bonus);
  }

  printf ("ALL TESTS OK\n");

/*
  printf ("SIMPLE FIXED TESTS.\n");
  for (p = 0; p < 2; p++) {
    for (deckCount = 0; deckCount < 5; deckCount++) {
      for (discardCount = 0; discardCount < 5; discardCount++) {
	for (handCount = 0; handCount < 5; handCount++) {
	  memset(&G, 23, sizeof(struct gameState)); 
	  r = initializeGame(2, k, 1, &G);
	  G.deckCount[p] = deckCount;
	  memset(G.deck[p], 0, sizeof(int) * deckCount);
	  G.discardCount[p] = discardCount;
	  memset(G.discard[p], 0, sizeof(int) * discardCount);
	  G.handCount[p] = handCount;
	  memset(G.hand[p], 0, sizeof(int) * handCount);
          test_adventurer(card, choice1, choice2, choice3, &G, handPos, bonus);
	}
      }
    }
  }
*/
  return 0;
}
